<template>
  <!-- 通用的编辑表单组件 -->
  <div class="editForm-wrap">
    <el-dialog
      :visible="show"
      v-bind="$attrs"
      :close-on-click-modal="false"
      @close="close"
    >
      <div slot="title">
        <slot name="title">
          <!-- 标题的默认形式 -->
          标题
        </slot>
      </div>
      <!-- 表单容器 -->
      <div v-if="Object.keys(this.form).length" class="form-content">
        <el-form ref="form" :model="form" :rules="rules" label-width="135px">
          <!-- form-item,before 前置表单项插槽 -->
          <slot name="form-item-before" v-bind="form" />
          <div
            v-for="(val, key, index) in formdata"
            :key="index"
            class="form-item"
          >
            <!-- radio 单选框组 -->
            <el-form-item
              v-if="val.radio_roup && !val.disabled"
              class="radio-box"
              :label="val.label"
              :prop="key"
            >
              <el-radio-group v-model="form[key]">
                <!-- 对象数组形式 -->
                <template v-if="val.radio_roup[0] instanceof Object">
                  <el-radio
                    v-for="(item, index1) in val.radio_roup"
                    :key="index1"
                    size="mini"
                    :label="item.label"
                  >
                    {{ item.text || "" }}
                  </el-radio>
                </template>
                <!-- 字符串数组形式 -->
                <template v-else>
                  <el-radio
                    v-for="(item, index2) in val.radio_roup"
                    :key="index2"
                    :label="item"
                  />
                </template>
              </el-radio-group>
            </el-form-item>
            <!-- checkbox 复选框组 -->
            <el-form-item
              v-else-if="val.checkbox && !val.disabled"
              class="checkbox-box"
              :label="val.label"
              :prop="key"
            >
              <el-checkbox-group v-model="form[key]" size="mini">
                <!-- 对象数组形式 -->
                <template v-if="val.checkbox[0] instanceof Object">
                  <el-checkbox
                    v-for="(item, index1) in val.checkbox"
                    :key="index1"
                    v-bind="item"
                    >{{ item.text }}
                  </el-checkbox>
                </template>
                <!-- 字符串数组形式 -->
                <template v-else>
                  <el-checkbox
                    v-for="(item, index2) in val.checkbox"
                    :key="index2"
                    :label="item"
                  />
                </template>
              </el-checkbox-group>
            </el-form-item>
            <!-- switch 切换 -->
            <el-form-item
              v-else-if="val.switch && !val.disabled"
              class="switch-box"
              :label="val.label"
              :prop="key"
            >
              <el-switch
                v-model="form[key]"
                size="mini"
                v-bind="val.config && val.config.props"
                v-on="val.config && val.config.events"
              />
            </el-form-item>
            <!-- select 下拉选择 -->
            <el-form-item
              v-else-if="val.select && !val.disabled"
              class="select-box"
              :label="val.label"
              :prop="key"
            >
              <el-select
                v-model="form[key]"
                size="mini"
                :multiple="form[key] instanceof Array"
                v-bind="val.config && val.config.props"
                placeholder="请选择"
                v-on="val.config && val.config.events"
              >
                <el-option
                  v-for="(item, index1) in val.select"
                  :key="index1"
                  :label="item.label"
                  :value="item.value"
                />
              </el-select>
            </el-form-item>
            <!-- date 日期选择 -->
            <el-form-item
              v-else-if="val.date && !val.disabled"
              class="date-box"
              :label="val.label"
              :prop="key"
            >
              <el-date-picker
                v-model="form[key]"
                size="mini"
                type="date"
                v-bind="val.config && val.config.props"
                placeholder="选择日期"
                v-on="val.config && val.config.events"
              />
            </el-form-item>
            <!-- textarea 文本域 -->
            <el-form-item
              v-else-if="val.textarea && !val.disabled"
              class="textarea-box"
              :label="val.label"
              :prop="key"
            >
              <el-input
                v-model="form[key]"
                size="mini"
                type="textarea"
                v-bind="val.config && val.config.props"
              />
            </el-form-item>
            <!-- 文件上传 -->
            <el-form-item
              v-else-if="val.file"
              class="input-box"
              :label="val.label"
              :prop="key"
            >
              <el-input
                v-model="form[key]"
                size="mini"
                v-bind="val.config && val.config.props"
                disabled
              />
              <el-button type="primary" size="mini" @click="uploadFile(key)"
                >点击上传文件</el-button
              >
            </el-form-item>
            <!-- input 默认的文本输入框 -->
            <el-form-item
              v-else-if="!val.disabled"
              class="input-box"
              :label="val.label"
              :prop="key"
            >
              <el-input
                v-model="form[key]"
                size="mini"
                v-bind="val.config && val.config.props"
                v-on="val.config && val.config.events"
              />
            </el-form-item>
          </div>
          <!-- form-item,after 后置表单项插槽 -->
          <slot name="form-item-after" v-bind="form" />
        </el-form>
      </div>
      <div slot="footer" class="dialog-footer">
        <slot name="bottom-btn" />
        <el-button size="mini" @click="close">取 消</el-button>
        <el-button size="mini" type="primary" @click="confirm">确 定</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import { selectMultifile } from "@/utils/file.js";

export default {
  name: "EditForm",
  inheritAttrs: false,
  props: {
    show: {
      type: Boolean,
      default: false,
    },
    /**
     * 编辑的表单配置数据
     * {
     *   name:{
     *     // value:text, default:props
     *     // lable:text,
     *     // value(Boolean|text,...type) radio_roup:([text] | [label,value])
     *     // value:Boolean, switch:true, config:{props,events}
     *     // value:Array, checkbox:([text] | [label,value])
     *     // value:(text|Array), select:(Array), config:{props,events}
     *     // value:text, textarea:true,   config:{props,events}
     *     // value:text, date:(Date)
     *     value:'text', // Date,Number,Boolean(radio:true)
     *   },...
     *   ---------------
     *   所以统一有的值:{
     *     lable:text,    // 显示的标题
     *     value:text     // 输入框的值, 可选
     *     config:{
     *       props:{}, // el输入框支持的属性
     *       on:{},    // el输入框支持的事件
     *     }
     *   }
     *   ---------------
     *   单纯输入框:
     *   key:{
     *     // 默认
     *   }
     *   单选框组:
     *   key:{
     *     // 新增
     *     radio_roup:[
     *       {
     *         label:any,  // 单选框选中的值
     *         text:String // 单选宽显示的文字
     *       }
     *     ]
     *   }
     *   -----------------
     *   switch切换
     *   sex: {
          label: '性别',
          value: false,
          switch: true,
          config: {
            props: {
              'active-text': '男',
              'inactive-text': '女'
            }
          }
        }
        ----------------
        checkbox 复选框
        key:{
          checkbox:[
            {label,text}
          ]
        },
        下拉切换
        key:{
          select: [
              { label: '普通用户', value: 0 },
              { label: '会员', value: 1 }
            ]
        }
     * }
     */
    formdata: {
      type: Object,
      required: true,
      default: () => {
        return {};
      },
    },
    // 表单的校验规则
    rules: {
      type: Object,
      default: () => {
        return {};
      },
    },
  },
  data() {
    return {
      form: {},
    };
  },
  watch: {
    formdata: {
      handler(val, old) {
        this.changeform();
      },
      immediate: true,
      deep: true,
    },
    show(val) {
      if (val) {
        // 清空 from 表单
        this.form = {};
        this.changeform();
      }
    },
  },
  created() {
    this.changeform();
  },
  methods: {
    setForm(obj) {
      this.form = obj;
    },
    confirm() {
      this.$refs.form.validate((valid) => {
        if (valid) {
          this.$emit("confirm", this.form);
        }
      });
    },
    changeform() {
      const tem = {};
      for (const key in this.formdata) {
        tem[key] =
          this.formdata[key].value === undefined
            ? ""
            : this.formdata[key].value;
      }

      // 调用Vue 原型上的合并选项函数功能
      // console.log(this.form,tem)

      this.form = this.mergeOptions(tem, this.form);
      // console.log(this.form)
    },
    close() {
      this.$emit("update:show", false);
      this.$refs.form.clearValidate();
      this.$emit("close");
    },
    // 上传文件
    uploadFile(key) {
      selectMultifile(
        async (input) => {
          const formData = new FormData();
          let filename = input.files[0].name;
          formData.append("file", input.files[0]);
          // 处理中文文件名
          if (/.*[\u4e00-\u9fa5]+.*$/.test(filename)) {
            const tem = filename.split(".");
            filename = new Date().getTime() + "." + tem[tem.length - 1];
          }
          this.$message.info("正在上传，请稍等！");
          const results = await this.$store.dispatch("upload/upload", formData);
          this.form[key] = results[0];
          this.$message.success("上传成功，请继续！");
        },
        "*",
        false
      );
    },
  },
};
</script>

<style scoped lang="scss">
/*
* $size : 滚动条滑块大小
* $direction: 滚动条方向,true:垂直
*/
@mixin scrollBar($size: 8px, $direction: true) {
  &::-webkit-scrollbar-track-piece {
    background: #d3dce6;
  }
  &::-webkit-scrollbar {
    @if ($direction) {
      width: $size;
    } @else {
      height: $size;
    }
  }
  &::-webkit-scrollbar-thumb {
    background: #99a9bf;
    border-radius: 20px;
  }
}

.editForm-wrap {
  .el-dialog {
    min-width: 500px;
  }

  ::v-deep .el-dialog__body {
    @include scrollBar;
    max-height: calc(90vh - 200px);
    overflow: auto;
  }
}
</style>
